package com.github.fujianlian.klinechart;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ProgressBar;

import androidx.annotation.ColorRes;
import androidx.annotation.DimenRes;
import androidx.core.content.ContextCompat;

import com.github.fujianlian.klinechart.base.IChartDraw;
import com.github.fujianlian.klinechart.draw.CCIDraw;
import com.github.fujianlian.klinechart.draw.KDJDraw;
import com.github.fujianlian.klinechart.draw.MACDDraw;
import com.github.fujianlian.klinechart.draw.MainDraw;
import com.github.fujianlian.klinechart.draw.RSIDraw;
import com.github.fujianlian.klinechart.draw.SKDJDraw;
import com.github.fujianlian.klinechart.draw.VolumeDraw;
import com.github.fujianlian.klinechart.draw.WRDraw;
import com.github.fujianlian.klinechart.draw.main.BOLLDraw;
import com.github.fujianlian.klinechart.draw.main.BaseMainDraw;
import com.github.fujianlian.klinechart.draw.main.ENEDraw;
import com.github.fujianlian.klinechart.draw.main.MaDraw;

import com.github.fujianlian.klinechart.entity.h.ICandle;


/**
 * k线图
 * Created by tian on 2016/5/20.
 */
public class KLineChartView extends BaseKLineChartView<ICandle> {
    AttributeSet attrs;
    ProgressBar mProgressBar;
    private boolean isRefreshing = false;
    private boolean isLoadMoreEnd = false;
    private boolean mLastScrollEnable;
    private boolean mLastScaleEnable;

    private KChartRefreshListener mRefreshListener;
    private OnVerticalScrollListener mVerticalScrollListener;

    public KLineChartView(Context context) {
        this(context, null);
    }

    public KLineChartView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public KLineChartView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
        initAttrs(attrs);
    }

    private void initView() {
        mProgressBar = new ProgressBar(getContext());
        LayoutParams layoutParams = new LayoutParams(dp2px(50), dp2px(50));
        layoutParams.addRule(CENTER_IN_PARENT);
        addView(mProgressBar, layoutParams);
        mProgressBar.setVisibility(GONE);

        setMainDraw(new MainDraw(this));

        addMainDraw(new MaDraw(this));
        addMainDraw(new BOLLDraw(this));
        addMainDraw(new ENEDraw(this));


    }
    public void addMainDraw(BaseMainDraw draw) {
        if (  getMainDraw() == null  )
            return;
        getMainDraw().addMainDraw(draw);
    }

    public void removeMainDraw(BaseMainDraw draw) {
        if (  getMainDraw() == null  )
            return;
        getMainDraw().removeMainDraw(draw);
    }


    public void changgeColor(boolean changeColor) {

        MainDraw chartPosition = getMainDraw();
        if (chartPosition != null) {
            chartPosition.changgeColor(changeColor);
            postInvalidate();
        }
    }

    public void setVerticalScrollListener(OnVerticalScrollListener mVerticalScrollListener) {
        this.mVerticalScrollListener = mVerticalScrollListener;
    }

    public void setSkdjLines(float lineTop, float lineBottom) {
        SKDJDraw mSkdjDraw = (SKDJDraw) getChartAtType(ChildDrawType.mSkdjDraw.type);
        if (null == mSkdjDraw) return;
        mSkdjDraw.setLineTop(lineTop);
        mSkdjDraw.setLineBottom(lineBottom);
    }

    public void setCCILines(float lineTop, float lineBottom) {
        CCIDraw mCCIDraw = (CCIDraw) getChartAtType(ChildDrawType.mCCIDraw.type);
        if (null == mCCIDraw) return;
        mCCIDraw.setLineTop(lineTop);
        mCCIDraw.setLineBottom(lineBottom);
    }

    public void setRSILines(float lineTop, float lineBottom) {
        RSIDraw mRSIDraw = (RSIDraw) getChartAtType(ChildDrawType.mRSIDraw.type);
        if (null == mRSIDraw) return;
        mRSIDraw.setLineTop(lineTop);
        mRSIDraw.setLineBottom(lineBottom);
    }

    public void switchChildDraw(ChildDrawType childDrawType, boolean show) {

        IChartDraw chartDraw = getChartAtType(childDrawType.getType());

        showOrHideDraw(chartDraw == null ? childDrawType.createChildDraw(this) : chartDraw, show);
    }

    private void showOrHideDraw(IChartDraw chartDraw, boolean show) {
        if (show) {
            addChildDraw(chartDraw);
        } else {
            hideChildDraw(chartDraw);
        }
    }


    public void reInitAttrs() {
        initAttrs(attrs);
        postInvalidate();
    }

    private void initAttrs(AttributeSet attrs) {
        this.attrs = attrs;
        TypedArray array = getContext().obtainStyledAttributes(attrs, R.styleable.KLineChartView);
        if (array != null) {
            try {
                //public
                setPointWidth(array.getDimension(R.styleable.KLineChartView_kc_point_width, getDimension(R.dimen.chart_point_width)));
                setTextSize(array.getDimension(R.styleable.KLineChartView_kc_text_size, getDimension(R.dimen.chart_text_size)));
                setTextColor(array.getColor(R.styleable.KLineChartView_kc_text_color, getColor(R.color.chart_text)));
                setMTextSize(array.getDimension(R.styleable.KLineChartView_kc_text_size, getDimension(R.dimen.chart_text_size)));
                setMTextColor(array.getColor(R.styleable.KLineChartView_kc_text_color, getColor(R.color.chart_text)));
                setLineWidth(array.getDimension(R.styleable.KLineChartView_kc_line_width, getDimension(R.dimen.chart_line_width)));
                setBackgroundColor(array.getColor(R.styleable.KLineChartView_kc_background_color, getColor(R.color.chart_bac)));
                setSelectPointColor(array.getColor(R.styleable.KLineChartView_kc_background_color, getColor(R.color.chart_point_bac)));

                setSelectedXLineColor(getColor(R.color.selected_line));
                setSelectedXLineWidth(getDimension(R.dimen.chart_line_width));

                setSelectedYLineColor(getColor(R.color.selected_line));
                setSelectedYLineWidth(getDimension(R.dimen.chart_point_width));

                setGridLineWidth(array.getDimension(R.styleable.KLineChartView_kc_grid_line_width, getDimension(R.dimen.chart_grid_line_width)));
                setGridLineColor(array.getColor(R.styleable.KLineChartView_kc_grid_line_color, getColor(R.color.chart_grid_line)));
                //macd
                setMACDWidth(array.getDimension(R.styleable.KLineChartView_kc_macd_width, getDimension(R.dimen.chart_candle_width)));
                setDIFColor(array.getColor(R.styleable.KLineChartView_kc_dif_color, getColor(R.color.chart_ma5)));
                setDEAColor(array.getColor(R.styleable.KLineChartView_kc_dea_color, getColor(R.color.chart_ma10)));
                setMACDColor(array.getColor(R.styleable.KLineChartView_kc_macd_color, getColor(R.color.chart_ma30)));
                //kdj
                setKColor(array.getColor(R.styleable.KLineChartView_kc_dif_color, getColor(R.color.chart_ma5)));
                setDColor(array.getColor(R.styleable.KLineChartView_kc_dea_color, getColor(R.color.chart_ma10)));
                setJColor(array.getColor(R.styleable.KLineChartView_kc_macd_color, getColor(R.color.chart_ma30)));
                //wr
                setRColor(array.getColor(R.styleable.KLineChartView_kc_dif_color, getColor(R.color.chart_ma5)));
                //rsi
                setRSI1Color(array.getColor(R.styleable.KLineChartView_kc_dif_color, getColor(R.color.chart_ma5)));
                setRSI2Color(array.getColor(R.styleable.KLineChartView_kc_dea_color, getColor(R.color.chart_ma10)));
                setRSI3Color(array.getColor(R.styleable.KLineChartView_kc_macd_color, getColor(R.color.chart_ma30)));
                //main
                setMa5Color(array.getColor(R.styleable.KLineChartView_kc_dif_color, getColor(R.color.chart_ma5)));
                setMa10Color(array.getColor(R.styleable.KLineChartView_kc_dea_color, getColor(R.color.chart_ma10)));
                setMa30Color(array.getColor(R.styleable.KLineChartView_kc_macd_color, getColor(R.color.chart_ma30)));
                setCandleWidth(array.getDimension(R.styleable.KLineChartView_kc_candle_width, getDimension(R.dimen.chart_candle_width)));
                setCandleLineWidth(array.getDimension(R.styleable.KLineChartView_kc_candle_line_width, getDimension(R.dimen.chart_candle_line_width)));
                setSelectorBackgroundColor(array.getColor(R.styleable.KLineChartView_kc_selector_background_color, getColor(R.color.chart_selector)));
                setSelectorTextSize(array.getDimension(R.styleable.KLineChartView_kc_selector_text_size, getDimension(R.dimen.chart_selector_text_size)));
                setCandleSolid(array.getBoolean(R.styleable.KLineChartView_kc_candle_solid, false));
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                array.recycle();
            }
        }
    }

    private float getDimension(@DimenRes int resId) {
        return getResources().getDimension(resId);
    }

    private int getColor(@ColorRes int resId) {
        return ContextCompat.getColor(getContext(), resId);
    }

    @Override
    public void onLeftSide() {
        showLoading();
    }

    @Override
    public void onRightSide() {
    }

    public void showLoading() {
        if (!isLoadMoreEnd && !isRefreshing) {
            isRefreshing = true;
            if (mProgressBar != null) {
                mProgressBar.setVisibility(View.VISIBLE);
            }
            if (mRefreshListener != null) {
                mRefreshListener.onLoadMoreBegin(this);
            }
            mLastScaleEnable = isScaleEnable();
            mLastScrollEnable = isScrollEnable();
            super.setScrollEnable(false);
            super.setScaleEnable(false);
        }
    }

    public void justShowLoading() {
        if (!isRefreshing) {
            isLongPress = false;
            isRefreshing = true;
            if (mProgressBar != null) {
                mProgressBar.setVisibility(View.VISIBLE);
            }
            if (mRefreshListener != null) {
                mRefreshListener.onLoadMoreBegin(this);
            }
            mLastScaleEnable = isScaleEnable();
            mLastScrollEnable = isScrollEnable();
            super.setScrollEnable(false);
            super.setScaleEnable(false);
        }
    }

    private void hideLoading() {
        if (mProgressBar != null) {
            mProgressBar.setVisibility(View.GONE);
        }
        super.setScrollEnable(mLastScrollEnable);
        super.setScaleEnable(mLastScaleEnable);
    }

    /**
     * 隐藏选择器内容
     */
    public void hideSelectData() {
        isLongPress = false;
        invalidate();
    }

    /**
     * 刷新完成
     */
    public void refreshComplete() {
        isRefreshing = false;
        hideLoading();
    }

    /**
     * 刷新完成，没有数据
     */
    public void refreshEnd() {
        isLoadMoreEnd = true;
        isRefreshing = false;
        hideLoading();
    }

    /**
     * 重置加载更多
     */
    public void resetLoadMoreEnd() {
        isLoadMoreEnd = false;
    }

    public void setLoadMoreEnd() {
        isLoadMoreEnd = true;
    }

    public interface KChartRefreshListener {
        /**
         * 加载更多
         *
         * @param chart
         */
        void onLoadMoreBegin(KLineChartView chart);
    }

    @Override
    public void setScaleEnable(boolean scaleEnable) {
        if (isRefreshing) {
            throw new IllegalStateException("请勿在刷新状态设置属性");
        }
        super.setScaleEnable(scaleEnable);

    }

    @Override
    public void setScrollEnable(boolean scrollEnable) {
        if (isRefreshing) {
            throw new IllegalStateException("请勿在刷新状态设置属性");
        }
        super.setScrollEnable(scrollEnable);
    }


    private MACDDraw macdDraw() {
        return (MACDDraw) getChartAtType(ChildDrawType.mMACDDraw.getType());
    }

    private VolumeDraw volumeDraw() {
        return (VolumeDraw) getChartAtType(ChildDrawType.mVolumeDraw.getType());
    }


    private KDJDraw kdjDraw() {
        return (KDJDraw) getChartAtType(ChildDrawType.mKDJDraw.getType());
    }

    private SKDJDraw skdjDraw() {
        return (SKDJDraw) getChartAtType(ChildDrawType.mSkdjDraw.getType());
    }

    private CCIDraw cciDraw() {
        return (CCIDraw) getChartAtType(ChildDrawType.mCCIDraw.getType());
    }

    private RSIDraw rsiDraw() {
        return (RSIDraw) getChartAtType(ChildDrawType.mRSIDraw.getType());
    }

    private WRDraw wrDraw() {
        return (WRDraw) getChartAtType(ChildDrawType.mWRDraw.getType());
    }


    /**
     * 设置DIF颜色
     */
    public void setDIFColor(int color) {
        MACDDraw macdDraw = macdDraw();
        if (null == macdDraw)
            return;
        macdDraw.setDIFColor(color);
    }


    /**
     * 设置DEA颜色
     */
    public void setDEAColor(int color) {
        MACDDraw macdDraw = macdDraw();
        if (null == macdDraw)
            return;
        macdDraw.setDEAColor(color);
    }

    /**
     * 设置MACD颜色
     */
    public void setMACDColor(int color) {
        MACDDraw macdDraw = macdDraw();
        if (null == macdDraw)
            return;
        macdDraw.setMACDColor(color);
    }

    /**
     * 设置MACD的宽度
     *
     * @param MACDWidth
     */
    public void setMACDWidth(float MACDWidth) {
        MACDDraw macdDraw = macdDraw();
        if (null == macdDraw)
            return;
        macdDraw.setMACDWidth(MACDWidth);
    }

    /**
     * 设置K颜色
     */
    public void setKColor(int color) {
        KDJDraw kdjDraw = kdjDraw();
        if (null == kdjDraw)
            return;
        kdjDraw.setKColor(color);
    }


    /**
     * 设置D颜色
     */
    public void setDColor(int color) {
        KDJDraw kdjDraw = kdjDraw();
        if (null == kdjDraw)
            return;
        kdjDraw.setDColor(color);
    }

    /**
     * 设置J颜色
     */
    public void setJColor(int color) {
        KDJDraw kdjDraw = kdjDraw();
        if (null == kdjDraw)
            return;
        kdjDraw.setJColor(color);
    }

    /**
     * 设置R颜色
     */
    public void setRColor(int color) {

        if (null != wrDraw())
            wrDraw().setRColor(color);
    }

    /**
     * 设置ma5颜色
     *
     * @param color
     */
    public void setMa5Color(int color) {
        if (null != getMainDraw())
            getMainDraw().setMa5Color(color);
        if (null != volumeDraw())
            volumeDraw().setMa5Color(color);
    }

    /**
     * 设置ma10颜色
     *
     * @param color
     */
    public void setMa10Color(int color) {
        if (null != getMainDraw())
            getMainDraw().setMa10Color(color);
        if (null != volumeDraw())
            volumeDraw().setMa10Color(color);
    }

    /**
     * 设置ma20颜色
     *
     * @param color
     */
    public void setMa30Color(int color) {
        if (null != getMainDraw())
            getMainDraw().setMa30Color(color);
    }

    /**
     * 设置选择器文字大小
     *
     * @param textSize
     */
    public void setSelectorTextSize(float textSize) {
        if (null != getMainDraw())
            getMainDraw().setSelectorTextSize(textSize);
    }

    /**
     * 设置选择器背景
     *
     * @param color
     */
    public void setSelectorBackgroundColor(int color) {
        if (null != getMainDraw())
            getMainDraw().setSelectorBackgroundColor(color);
    }

    /**
     * 设置蜡烛宽度
     *
     * @param candleWidth
     */
    public void setCandleWidth(float candleWidth) {
        if (null != getMainDraw())
            getMainDraw().setCandleWidth(candleWidth);
    }

    /**
     * 设置蜡烛线宽度
     *
     * @param candleLineWidth
     */
    public void setCandleLineWidth(float candleLineWidth) {
        if (null != getMainDraw())
            getMainDraw().setCandleLineWidth(candleLineWidth);
    }

    /**
     * 蜡烛是否空心
     */
    public void setCandleSolid(boolean candleSolid) {
        if (null != getMainDraw())
            getMainDraw().setCandleSolid(candleSolid);
    }

    public void setRSI1Color(int color) {
        if (null != rsiDraw())
            rsiDraw().setRSI1Color(color);
    }

    public void setRSI2Color(int color) {
        if (null != rsiDraw())
            rsiDraw().setRSI2Color(color);
    }

    public void setRSI3Color(int color) {
        if (null != rsiDraw())
            rsiDraw().setRSI3Color(color);
    }

    @Override
    public void setTextSize(float textSize) {
        super.setTextSize(textSize);
        if (null != getMainDraw())
            getMainDraw().setTextSize(textSize);
        if (null != rsiDraw())
            rsiDraw().setTextSize(textSize);
        if (null != macdDraw())
            macdDraw().setTextSize(textSize);
        if (null != skdjDraw())
            skdjDraw().setTextSize(textSize);
        if (null != kdjDraw())
            kdjDraw().setTextSize(textSize);
        if (null != wrDraw())
            wrDraw().setTextSize(textSize);
        if (null != volumeDraw())
            volumeDraw().setTextSize(textSize);
    }

    @Override
    public void setLineWidth(float lineWidth) {
        super.setLineWidth(lineWidth);
        if (null != getMainDraw())
            getMainDraw().setLineWidth(lineWidth);
        if (null != rsiDraw())
            rsiDraw().setLineWidth(lineWidth);
        if (null != macdDraw())
            macdDraw().setLineWidth(lineWidth);
        if (null != kdjDraw())
            kdjDraw().setLineWidth(lineWidth);
        if (null != wrDraw())
            wrDraw().setLineWidth(lineWidth);
        if (null != skdjDraw())
            skdjDraw().setLineWidth(lineWidth);
        if (null != volumeDraw())
            volumeDraw().setLineWidth(lineWidth);
    }

    @Override
    public void setTextColor(int color) {
        super.setTextColor(color);
        if (null != getMainDraw())
            getMainDraw().setSelectorTextColor(color);
    }

    /**
     * 设置刷新监听
     */
    public void setRefreshListener(KChartRefreshListener refreshListener) {
        mRefreshListener = refreshListener;
    }

    public void setMainDrawLine(boolean isLine) {
        this.isLine = isLine;
        super.setMainDrawLine(isLine);
        if (null != getMainDraw())
            getMainDraw().setLine(isLine);
        invalidate();
    }

    private int startX;
    private int startY;

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startX = (int) ev.getX();
                startY = (int) ev.getY();
                lstY = startY;
                break;
            case MotionEvent.ACTION_MOVE:
                int dX = (int) (ev.getX() - startX);
                int dY = (int) (ev.getY() - startX);
                if (Math.abs(dX) > Math.abs(dY)) {
                    //左右滑动
                    return true;
                } else {
                    //上下滑动
                    if (isMainRect()) {
                        return true;
                    }
                }
            case MotionEvent.ACTION_UP:
                break;
            default:
        }
        return super.onInterceptTouchEvent(ev);
    }

    int lstY;
    int lstX;
    boolean scalMode = false;
    boolean moveMode = false;

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        if (isMainRect()) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_POINTER_DOWN:
                    if (!scalMode) {

                    }
                    break;
                case MotionEvent.ACTION_POINTER_UP:

                    break;
                case MotionEvent.ACTION_DOWN:
                    lstY = (int) event.getY();
                    lstX = (int) event.getX();
                    break;
                case MotionEvent.ACTION_MOVE:
                    float dy = Math.abs(event.getY() - lstY);
                    float dx = Math.abs(event.getX() - lstX);
                    if ( dx>20||dy>20 ) {
                        if (scalMode) {
                            onVerticalScroll((int) (event.getY() - lstY));
                            lstY = (int) event.getY();
                        } else if (!moveMode) {
                            if (dy - dx > 5) {
                                scalMode = true;
                            } else {
                                moveMode = true;
                            }
                        } else {

                        }
                    }
                    break;

                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    scalMode = false;
                    moveMode = false;
                    break;
            }
        }else {
            switch (event.getAction()) {
               
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    scalMode = false;
                    moveMode = false;
                    Log.e(VIEW_LOG_TAG , " cancel_mode");

                    break;
            }
        }
        return super.onTouchEvent(event);
    }

    private boolean isMainRect() {
        return startY > getmMainRect().top && startY < getmMainRect().bottom;
    }

    private void onVerticalScroll(int dY) {
        if (mVerticalScrollListener != null && !isLongPress)
            mVerticalScrollListener.onVerticalScroll(dY);
    }

    @Override
    public void onLongPress(MotionEvent e) {
        if (!isRefreshing) {
            super.onLongPress(e);
        }
    }
}
